home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / m2 / cat3src / cat / editglob.i < prev    next >
Text File  |  1997-10-26  |  23KB  |  800 lines

  1. IMPLEMENTATION MODULE EditGlobals;
  2.  
  3. FROM SYSTEM     IMPORT  ADDRESS, ADR, TSIZE, CADR, LOC, LONGWORD, CALLSYS;
  4.  
  5. (* Megamax-Lib *)
  6.  
  7. FROM GrafBase   IMPORT LongRect, Rectangle, Point;
  8.  
  9. IMPORT BinOps, Strings, Block;
  10.  
  11. FROM Storage IMPORT ALLOCATE, DEALLOCATE;
  12.  
  13. (* MagicLib *)
  14. IMPORT MagicAES, MagicVDI, MagicFSM, MagicDOS, MagicSys, MagicTypes, mtAppl;
  15.  
  16. FROM MagicVDI   IMPORT VDIIntIn, VDIPtsIn, VDIControl, VDICall;
  17.  
  18. (* CAT Module *)
  19. IMPORT WdwManager;
  20. IMPORT RectFuncs;
  21. IMPORT CatGlobal;
  22.  
  23. FROM Void       IMPORT v;
  24.  
  25. (* Editor *)
  26. FROM EditTypes  IMPORT EDITPTR, aLinePtr, aLineDesc, aMark, textPtr, deskSize, pixOff,
  27.                        theDrawLine, CharSet, TrennSet, cursorHandle;
  28.  
  29. IMPORT EditBase;
  30.  
  31. FROM Characters IMPORT TAB, CR, LF;
  32.  
  33.  
  34.         (* Window-Funktionen fr Darstellung auf Bildschirm *)
  35.  
  36. (* Setzt neues virtuelles Fenster *)
  37. PROCEDURE SetDocument (ed : EDITPTR);
  38.   VAR r : LongRect;
  39. BEGIN
  40.   WITH ed^ DO
  41.     WdwManager.SetWdwDocument (wdw, LongRect{LONG(leftOffset), StartLine, LONG(maxWidth), totalLineNr-1});
  42.   END;
  43. END SetDocument;
  44.  
  45. PROCEDURE AllocNew (VAR line : aLineDesc; newLen : INTEGER);
  46.   VAR newLength : INTEGER;
  47.       tBuf      : textPtr;
  48. BEGIN
  49.   IF newLen >= line.length-1
  50.   THEN
  51.     newLength := ((newLen + 16) DIV 16 ) * 16;
  52.     IF newLength < newLen THEN INC (newLength, 16) END;
  53.     ALLOCATE (tBuf, newLength);
  54.     IF tBuf = NIL 
  55.     THEN 
  56. (*      CompactAll (); *)
  57.       ALLOCATE (tBuf, newLength);
  58.       IF tBuf = NIL 
  59.       THEN
  60.         HALT (* kein Speicher mehr frei *) 
  61.       END;
  62.     END;
  63.     Block.Clear (tBuf, newLength);
  64.     Block.Copy (line.text, line.length, tBuf);
  65.     DEALLOCATE (line.text, 0);
  66.     line.text := tBuf;
  67.     line.length := newLength;
  68.   END;
  69. END AllocNew;
  70.  
  71.         (* GrafGrowbox und GrafShrinkbox neu, da das AES bei kleinen Boxgr”žen anscheinend Mll macht *)
  72.  
  73. PROCEDURE GrowAndShrink (ed : EDITPTR; from : Rectangle);
  74.   VAR pts : ARRAY [0..4] OF Point;
  75.       i, j, k : INTEGER;
  76.       diffw, 
  77.       diffh : INTEGER;
  78. BEGIN
  79.   WITH ed^ DO 
  80.     v.int := MagicVDI.SetLinetype (cursorHandle, MagicVDI.User);
  81.     (* MagicVDI.SetUserlinestyle (cursorHandle, $5555); *)
  82.     MagicVDI.SetUserlinestyle (cursorHandle, $FFFF);
  83.     diffw := BinOps.HigherInt (4, from.w DIV 2);
  84.     diffh := from.h DIV 2;
  85.     FOR j := 0 TO 3 DO 
  86.       FOR k := 0 TO 7 DO 
  87.         FOR i := 0 TO 10 DO 
  88.           pts[0].x := from.x - diffw * i;
  89.           pts[0].y := from.y - diffh * i;
  90.           pts[1].x := from.x + from.w - 1 + diffw * i ;
  91.           pts[1].y := pts[0].y;
  92.           pts[2].x := pts[1].x;
  93.           pts[2].y := from.y + from.h + diffh * i - 1;
  94.           pts[3].x := pts[0].x;
  95.           pts[3].y := pts[2].y;
  96.           pts[4] := pts[0];
  97.           MagicVDI.Polyline (cursorHandle, 5, pts);
  98.         END;
  99.         (* Hier irgendeine Wartefunktion einbauen *)
  100.         FOR i := 0 TO 1000 DO pts[0].x := 999 END;
  101.       END;
  102.     END;
  103.   END;
  104. END GrowAndShrink;
  105.  
  106.         (* VDI Text Funktionen    *)
  107.         
  108. PROCEDURE Text (ed : EDITPTR; x, y: INTEGER; REF string: ARRAY OF CHAR);
  109.           (* v_gtext *)
  110. BEGIN
  111.   IF string[0] = 0C THEN RETURN END;
  112.   WITH ed^ DO
  113.     IF isFSM
  114.     THEN
  115.       MagicFSM.FSMText (hdl, x, y+charHeight-1, string);
  116.     ELSE
  117.       MagicVDI.Text (hdl, x, y+charHeight-1, string);
  118.     END;
  119.   END;
  120. END Text;
  121.  
  122. PROCEDURE isQuote (REF str : ARRAY OF CHAR) : BOOLEAN;
  123.   VAR i, j, l : CARDINAL;
  124.       isQ: BOOLEAN;
  125.       ch : CHAR;
  126. BEGIN
  127.   i := 0;
  128.   l := LENGTH (str);
  129.   WHILE (i < l) & (str[i] = ' ') DO INC(i); END;
  130.   isQ := TRUE;
  131.   j := i;
  132.   WHILE (j <= i+5) & (str[j] # '>') & isQ DO
  133.     ch := str[j];
  134.     IF (j >= i+2) THEN ch := CAP(ch) END;
  135.     IF ch IN CharSet{'A'..'Z','Ž','™','š'} THEN 
  136.       INC (j)
  137.     ELSE
  138.       isQ := FALSE;
  139.     END;
  140.   END;
  141.   isQ := isQ & (j <= i+5);
  142.   RETURN isQ;
  143.   (*
  144.   RETURN (i<3) & (str[i]=">") OR ((str[i] IN CharSet{'A'..'Z'}) & ((str[i+1]=">") OR ((str[i+1] IN CharSet{'A'..'Z'}) & ((str[i+2]=">"))))
  145.          OR ((str[i+2] IN CharSet{'A'..'Z'}) & ((str[i+3]=">")  
  146.          OR ((str[i+3] IN CharSet{'A'..'Z'}) & ((str[i+4]=">"))))
  147.   *)
  148. END isQuote;
  149.  
  150. PROCEDURE GetQuote (REF str : ARRAY OF CHAR; VAR quote: ARRAY OF CHAR);
  151.   VAR i, j, l : CARDINAL;
  152.       isQ: BOOLEAN;
  153.       ch : CHAR;
  154. BEGIN
  155.   quote[0] := '';
  156.   i := 0;
  157.   l := LENGTH (str);
  158.   WHILE (i < l) & (str[i] = ' ') DO INC(i); END;
  159.   isQ := TRUE;
  160.   j := i;
  161.   WHILE (j <= i+5) & (str[j] # '>') & isQ DO
  162.     ch := str[j];
  163.     IF (j >= i+2) THEN ch := CAP(ch) END;
  164.     IF ch IN CharSet{'A'..'Z','Ž','™','š'} THEN 
  165.       INC (j)
  166.     ELSE
  167.       isQ := FALSE;
  168.     END;
  169.   END;
  170.   isQ := isQ & (j <= i+5);
  171.   IF isQ
  172.   THEN
  173.     Strings.Copy (str, 0, j+1, quote, v.bool);
  174.   END;
  175. END GetQuote;
  176.  
  177. PROCEDURE handleEffectLine (ed: EDITPTR; x, y: INTEGER; REF line: ARRAY OF CHAR; len: INTEGER; 
  178.                             doOutput: BOOLEAN; maxExtIdx: INTEGER; VAR ext: ARRAY OF Point);
  179. CONST NormalChars = CharSet{'A'..'Z','a'..'z','„','”','','ž','Ž','™','š','0'..'9','"',"'"};
  180.       delimiters  = CharSet{' ','-','>','(','[','{','"',"'"};
  181.       wordEnds = CharSet {0C, 12C, 15C, ' ','.',',',';','!','-','?',':','"',"'",'}',']',')'};
  182.  
  183.   VAR isQ : BOOLEAN;
  184.       display: ARRAY [0..4095] OF CHAR;
  185.       xOff   : INTEGER;
  186.       maxI,
  187.       i, j,
  188.       idx : INTEGER;
  189.       inEffect: BOOLEAN;
  190.       extend    : ARRAY [0..3] OF Point;
  191.       eff       : BITSET;
  192.       effChar   : CHAR;
  193.       chAdr     : POINTER TO CHAR;
  194.       saveCh    : CHAR;
  195.  
  196.   (*$W-*)
  197.   PROCEDURE simpleOutput();
  198.   BEGIN
  199.     WITH ed^ DO
  200.       (* Zeile einfach ausgeben *)
  201.       IF doOutput
  202.       THEN
  203.         Text (ed, x, y, line);
  204.       END;
  205.       IF ~monoSpaced OR isFSM (* added "OR isFSM" for Monospaced 821 Font *)
  206.       THEN
  207.         chAdr := ADR(line[maxExtIdx]);
  208.         saveCh := chAdr^;
  209.         chAdr^ := 0C;
  210.         (* Textadvance und damit xOffset berechnen *)
  211.         InqTextextend (ed, line, extend, FALSE);
  212.         chAdr^ := saveCh;
  213.         INC (xOff, extend[1].x - extend[0].x);
  214.       ELSE
  215.         INC (xOff, maxExtIdx*charWidth);
  216.       END;
  217.     END;
  218.   END simpleOutput;
  219.  
  220. BEGIN
  221.   WITH ed^ DO
  222.     xOff := 0;
  223.     IF (maxExtIdx >= SIZE(display))
  224.     OR ((maxExtIdx >= (mtAppl.MaxWidth * 2) DIV charWidth) & ~doOutput)
  225.     THEN
  226.       (* L„nge berschreitet maximal m”gliche Testl„nge,
  227.        * daher Breite als MAXINT zurckliefern 
  228.        *)
  229.       (* ext-Array fllen *)
  230.       FOR i := 0 TO 3 DO
  231.         ext[i].x := 0;
  232.         ext[i].y := 0;
  233.       END;
  234.       ext[0].x := 0;
  235.       ext[1].x := 32767;
  236.       RETURN ;
  237.     END;
  238.     IF readOnly 
  239.     THEN
  240.       isQ := isQuote (line);
  241.       IF isQ & (mtAppl.Bitplanes > 1)
  242.       THEN
  243.         (* Farbe umsetzen auf Quotefarbe *)
  244.         v.int := MagicVDI.SetTextcolor (hdl, quoteCol);
  245.       ELSIF isQ
  246.       THEN
  247.         (* Texteffekt umsetzen *)
  248.         v.bset := MagicVDI.SetTexteffect (hdl, quoteEff);
  249.       END;
  250.       IF parseEffects
  251.       THEN
  252.         (* Zeile parsen und ggf. Effekte einstellen *)
  253.         i := 0;
  254.         idx := 0;
  255.         xOff := 0;
  256.         inEffect := FALSE;
  257.         maxI := maxExtIdx;  (* vorher: maxI := len *)
  258.         eff := {};
  259.         WHILE (i < maxI) & (line[i] # '') DO
  260.           (* Solange Teilstrings kopieren, bis Sonderzeichen gefunden wurde *)
  261.           IF (line[i] IN CharSet{'*','_','/'})
  262.           THEN
  263.             IF inEffect 
  264.             THEN
  265.               (* Testen, ob Effect nicht beendet wird *)
  266.               IF (i < len-1) & ~(line[i+1] IN TrennSet) & (effChar = '_')
  267.               THEN
  268.                 IF line[i] = '_' THEN 
  269.                   display [idx] := ' ';
  270.                 ELSE
  271.                   display [idx] := line[i];
  272.                 END;
  273.                 INC (idx);
  274.               ELSIF (effChar = line[i]) & (line[i+1] IN wordEnds)
  275.               THEN
  276.                 (* Effekt beendet *)
  277.                 display[idx] := '';
  278.                 IF doOutput
  279.                 THEN
  280.                   (* Letzten Teil ausgeben *)
  281.                   Text (ed, x+xOff, y, display);
  282.                 END;
  283.                 (* Textadvance und damit xOffset berechnen *)
  284.                 InqTextextend (ed, display, extend, FALSE);
  285.                 INC (xOff, extend[1].x - extend[0].x);
  286.                 (* Effekt wieder abstellen *)
  287.                 eff := {};
  288.                 IF isQ & (mtAppl.Bitplanes <= 1) THEN eff := eff + quoteEff END;
  289.                 v.bset := MagicVDI.SetTexteffect (hdl, eff);
  290.                 idx := 0;
  291.                 inEffect := FALSE;
  292.               ELSE
  293.                 display[idx] := line[i];
  294.                 INC (idx);
  295.               END;
  296.             ELSE 
  297.               (* Nicht in Effekt, vielleicht ein neuer? *)
  298.               IF (i < len-1) & (line[i+1] IN NormalChars)
  299.                  & ((i=0) OR ((i>0) & (line[i-1] IN delimiters)))
  300.               THEN
  301.                 (* Jetzt noch testen, ob das Zeichen in der Zeile nochmal kommt *)
  302.                 j := i;
  303.                 REPEAT
  304.                   REPEAT
  305.                     INC(j);
  306.                   UNTIL (j >= len) OR (line[j] = line[i]);
  307.                 UNTIL (j >= len) OR (line[j+1] IN wordEnds);
  308.                 IF (j < len)
  309.                 THEN
  310.                   (* Beginn eines Effects *)
  311.                   inEffect := TRUE;
  312.                   (* Letzten Teil ausgeben *)
  313.                   display[idx] := '';
  314.                   IF doOutput
  315.                   THEN
  316.                     (* Textstck ausgeben *)
  317.                     Text (ed, x+xOff, y, display);
  318.                   END;
  319.                   (* Textadvance und damit xOffset berechnen *)
  320.                   InqTextextend (ed, display, extend, FALSE);
  321.                   INC (xOff, extend[1].x - extend[0].x);
  322.                   (* Jetzt Effekt setzen *)
  323.                   eff := {};
  324.                   IF (line[i] = '*')
  325.                   THEN
  326.                     (* Texteffekt umsetzen *)
  327.                     eff := {MagicVDI.Fat};
  328.                   ELSIF (line[i] = '/')
  329.                   THEN
  330.                     eff := {MagicVDI.Italic};
  331.                   ELSIF (line[i] = '_')
  332.                   THEN
  333.                     eff := {MagicVDI.Underline};
  334.                   END;
  335.                   IF isQ & (mtAppl.Bitplanes <= 1) THEN eff := eff + quoteEff END;
  336.                   v.bset := MagicVDI.SetTexteffect (hdl, eff);
  337.                   effChar := line[i];
  338.                   idx := 0;
  339.                 ELSE
  340.                   display[idx] := line[i];
  341.                   INC (idx);
  342.                 END;
  343.               ELSE
  344.                 display[idx] := line[i];
  345.                 INC (idx);
  346.               END;
  347.             END;
  348.           ELSE
  349.             display[idx] := line[i];
  350.             INC (idx);
  351.           END;
  352.           INC(i);
  353.         END;
  354.         IF idx > 0 
  355.         THEN
  356.           (* Text noch nicht ausgegeben *)
  357.           display[idx] := '';
  358.           IF doOutput
  359.           THEN
  360.             (* Text noch ausgeben *)
  361.             Text (ed, x+xOff, y, display);
  362.           END;
  363.           (* Textadvance und damit xOffset berechnen *)
  364.           InqTextextend (ed, display, extend, FALSE);
  365.           INC (xOff, extend[1].x - extend[0].x);
  366.         END;
  367.         (* Texteffekt wieder abstellen *)
  368.         v.bset := MagicVDI.SetTexteffect (hdl, {});
  369.       ELSE
  370.         (* Zeile einfach ausgeben *)
  371.         simpleOutput();
  372.         (*
  373.         IF doOutput
  374.         THEN
  375.           Text (ed, x, y, line);
  376.         END;
  377.         chAdr := ADR(line[maxExtIdx]);
  378.         saveCh := chAdr^;
  379.         chAdr^ := 0C;
  380.         (* Textadvance und damit xOffset berechnen *)
  381.         InqTextextend (ed, line, extend, FALSE);
  382.         chAdr^ := saveCh;
  383.         INC (xOff, extend[1].x - extend[0].x);
  384.         *)
  385.       END;
  386.       IF isQ & (mtAppl.Bitplanes > 1)
  387.       THEN
  388.         (* Farbe wieder zurcksetzen *)
  389.         v.int := MagicVDI.SetTextcolor (hdl, textCol);
  390.       ELSIF isQ
  391.       THEN
  392.         (* Texteffekt wieder zurcksetzen *)
  393.         v.bset := MagicVDI.SetTexteffect (hdl, {});
  394.       END;
  395.     ELSE
  396.       simpleOutput();
  397.       (*
  398.       IF doOutput
  399.       THEN
  400.         Text (ed, x, y, line);
  401.       END;
  402.       chAdr := ADR(line[maxExtIdx]);
  403.       saveCh := chAdr^;
  404.       chAdr^ := 0C;
  405.       (* Textadvance und damit xOffset berechnen *)
  406.       InqTextextend (ed, line, extend, FALSE);
  407.       chAdr^ := saveCh;
  408.       INC (xOff, extend[1].x - extend[0].x);
  409.       *)
  410.     END;
  411.     (* ext-Array fllen *)
  412.     FOR i := 0 TO 3 DO
  413.       ext[i] := extend[i];
  414.     END;
  415.     ext[0].x := 0;
  416.     ext[1].x := xOff;
  417.   END;
  418.   (*$W=*)
  419. END handleEffectLine;
  420.  
  421. PROCEDURE OutputLine (ed : EDITPTR; x, y : INTEGER; REF line : ARRAY OF CHAR; 
  422.                       len : INTEGER; VAR width : INTEGER);
  423.  VAR extend    : ARRAY [0..3] OF Point;
  424. BEGIN
  425.   handleEffectLine (ed, x, y, line, len, TRUE, len, extend);
  426.   width := extend[1].x - extend[0].x;
  427. END OutputLine;
  428.  
  429. PROCEDURE GetTextWidth (ed : EDITPTR; REF string: ARRAY OF CHAR; idx: INTEGER;
  430.                              VAR extent: ARRAY OF LOC);
  431. (* Diese Porzedur parst den Text immer. Idx gibt die Position an, bis zu der der 
  432.  * String maximal zusammengesetzt wird! 
  433.  *)
  434.  VAR extend     : POINTER TO ARRAY [0..3] OF Point;
  435. BEGIN
  436.   extend := ADR(extent);
  437.   handleEffectLine (ed, 0, 0, string, LENGTH(string), FALSE, idx, extend^);
  438. END GetTextWidth;
  439.  
  440. PROCEDURE InqTextextend (ed : EDITPTR; REF string: ARRAY OF CHAR;
  441.                              VAR extent: ARRAY OF LOC; parseEffects: BOOLEAN);
  442.           (* vqt_extent *)
  443.   VAR (*$Reg*) i : CARDINAL;
  444.       extend     : POINTER TO ARRAY [0..3] OF Point;
  445.       l          : INTEGER;
  446. BEGIN
  447.   IF string[0] = 0C THEN 
  448.     FOR i := 0 TO HIGH (extent)-1 DO extent[i] := 0; END;
  449.     RETURN
  450.   END;
  451.   IF ~parseEffects
  452.   THEN
  453.     WITH ed^ DO 
  454.       IF isFSM
  455.       THEN
  456.         MagicFSM.InqFExtent (hdl, string, extent);
  457.       ELSE 
  458.         MagicVDI.InqTextextent (hdl, string, extent);
  459.       END;
  460.     END;
  461.   ELSE
  462.     extend := ADR(extent);
  463.     l := LENGTH (string);
  464.     handleEffectLine (ed, 0, 0, string, l, FALSE, l, extend^);
  465.   END;
  466. END InqTextextend;
  467.  
  468. PROCEDURE RowToIndex (REF str : ARRAY OF CHAR; row, tabSize : INTEGER) : INTEGER;
  469.   VAR i, j : INTEGER;
  470. BEGIN
  471.   j := 0;
  472.   FOR i := 0 TO row - 1 DO
  473.     IF str[i] = TAB
  474.     THEN
  475.       j := ((j DIV tabSize) + 1) * tabSize;
  476.     ELSE
  477.       INC(j);
  478.     END;
  479.   END;
  480.   RETURN j;
  481. END RowToIndex;
  482.  
  483. PROCEDURE FixCursorPos (VAR ed : EDITPTR);
  484. (* Pažt auf, das der Cursor nie hinter einem CR/LF steht
  485.  *)
  486.   VAR (*$Reg*) tPtr: textPtr;
  487.       (*$Reg*) ch  : CHAR;
  488. BEGIN
  489.   WITH ed^ DO
  490.     IF (currRow > 0)
  491.     THEN
  492.       tPtr := editLine.text;
  493.       LOOP
  494.         (* IF (ORD(editLine.text^[currRow-1]) >= 20) OR (editLine.text^[currRow-1] = TAB) THEN EXIT END; *)
  495.         ch := tPtr^[currRow-1];
  496.         IF (ch # CR) & (ch # LF) THEN EXIT END;
  497.         DEC (currRow);
  498.         IF currRow <= 0 THEN EXIT END;
  499.       END;
  500.     END;
  501.   END;
  502. END FixCursorPos;
  503.  
  504.         (* Cursor-Zeichenfunktionen *)
  505.         
  506. PROCEDURE ClipWork (ed : EDITPTR);
  507.   VAR clip : Rectangle;
  508. BEGIN
  509.   clip := RectFuncs.ClipRect (deskSize, ed^.editWork);
  510.   WdwManager.SetClip (ed^.hdl, clip, TRUE);
  511. END ClipWork;
  512.  
  513. PROCEDURE getCursorRect (VAR ed : EDITPTR; VAR xy: ARRAY OF INTEGER);
  514.   VAR c, r : Rectangle;
  515.       extend    : ARRAY [0..3] OF Point;
  516.       ch  : ARRAY [0..1] OF CHAR;
  517.       saveCh : CHAR;
  518.       charAdr : POINTER TO CHAR;
  519.       text    : textPtr;
  520. BEGIN
  521.   WITH ed^ DO
  522.     IF (currLineNr >= totalLineNr) OR (readOnly & ~multiBlockMark) THEN RETURN END;
  523.     (* So geht's schneller: *)
  524.     (*
  525.     getCharPos (ed, currLineNr, currRow, c.x, c.y);
  526.     *)
  527.     IF ~EditBase.GetLineAdr (ed, currLineNr, text, v.int) THEN RETURN END;
  528.     IF currRow > v.int THEN currRow := v.int; END;
  529.     charAdr := ADR (text^[currRow]);
  530.     saveCh := charAdr^;
  531.     IF (currRow # cursPos.row) OR (currLineNr # cursPos.line)
  532.     THEN
  533.       IF ~monoSpaced OR realTabs OR isFSM   (* added "OR isFSM" for Monospaced 821 Font *)
  534.       THEN
  535.         (* String terminieren *)
  536.         charAdr^ := 0C;
  537.         IF realTabs 
  538.         THEN
  539.           CatGlobal.ConvertTabs (text^, theDrawLine, tabSize);
  540.           text := ADR (theDrawLine);
  541.         END;
  542.         (* Cursorposition bestimmen *)
  543.         InqTextextend (ed, text^, extend, FALSE);
  544.         (* Žnderung wieder rckg„ngig machen *)
  545.         charAdr^ := saveCh;
  546.         cursPos.x := extend[1].x - extend[0].x;
  547.       ELSE
  548.         cursPos.x := currRow * charWidth;
  549.         extend[1].x := cursPos.x;
  550.         extend[0].x := 0;
  551.       END;
  552.       cursPos.row := currRow;
  553.       cursPos.line := currLineNr;
  554.       
  555.     ELSE
  556.       extend[1].x := cursPos.x;
  557.       extend[0].x := 0;
  558.     END;
  559.     (*----*)
  560.     c.x := editWork.x + extend[1].x - extend[0].x + pixOff - leftOffset;
  561.     c.y := editWork.y + SHORT(currLineNr - StartLine) * charHeight;
  562.     xy[0] := c.x;
  563.     xy[1] := c.y - 1;
  564.     xy[3] := c.y + charHeight + 1;
  565.     IF insertMode THEN
  566.       xy[2]:= xy[0]+1;
  567.     ELSE
  568.       (* Zeichenausmaže holen *)
  569.       ch[1] := 0C;
  570.       ch[0] := saveCh;
  571.       IF (ch[0] = 0C) OR (monoSpaced & ~isFSM) THEN (* added "& ~isFSM" for Monospaced 821 Font *)
  572.         xy[2] := c.x + charWidth;
  573.       ELSE
  574.         InqTextextend (ed, ch, extend, FALSE);
  575.         xy[2] := c.x + extend[1].x - extend[0].x - 1;
  576.       END;
  577.       INC (xy[1]); DEC(xy[3]);
  578.     END;
  579.   END;
  580. END getCursorRect;
  581.  
  582. PROCEDURE drawCursor (VAR ed: EDITPTR; grow: BOOLEAN);
  583.   VAR xy : ARRAY [0..3] OF INTEGER;
  584.       r  : Rectangle;
  585. BEGIN
  586.   WITH ed^ DO
  587.     getCursorRect (ed, xy);
  588.     IF grow THEN
  589.       WITH r DO x := xy[0]; y := xy[1]; w := xy[2] - xy[0] + 1; h := xy[3] - xy[1] + 1;  END;
  590.       GrowAndShrink (ed, r);
  591.     ELSE
  592.       MagicVDI.FillRectangle (cursorHandle, xy);
  593.     END;
  594.   END;
  595. END drawCursor;
  596.  
  597. (*----------------------------------------------------------------------*
  598.  *                            M„usetreiberei                            *
  599.  *----------------------------------------------------------------------*)
  600.  
  601. VAR mouseCount : CARDINAL;
  602.     smCount    : CARDINAL;
  603.     smForm     : INTEGER;
  604.     smUser     : ADDRESS;
  605.     MausForm   : INTEGER;
  606.     Usermaus   : ADDRESS;
  607.     
  608. PROCEDURE SetMouse ();
  609. BEGIN
  610.   IF MausForm = MagicAES.USERDEF THEN
  611.    MagicAES.GrafMouse (MausForm, Usermaus);
  612.   ELSE
  613.    MagicAES.GrafMouse (MausForm, NIL);
  614.   END;
  615. END SetMouse;
  616.  
  617. PROCEDURE MouseArrow;
  618. BEGIN
  619.  MausForm:= MagicAES.ARROW;  SetMouse(); (* ShowMouse(FALSE); *)
  620. END MouseArrow;
  621.  
  622.  
  623. PROCEDURE MouseCursor;
  624. BEGIN
  625.  MausForm:= MagicAES.TEXTCRSR;  SetMouse();
  626. END MouseCursor;
  627.  
  628.  
  629. PROCEDURE MouseBusy;
  630. BEGIN
  631.  MausForm:= MagicAES.BUSYBEE;  SetMouse();
  632. END MouseBusy;
  633.  
  634.  
  635. PROCEDURE MouseFinger;
  636. BEGIN
  637.  MausForm:= MagicAES.POINTHAND;  SetMouse();
  638. END MouseFinger;
  639.  
  640.  
  641. PROCEDURE MouseHand;
  642. BEGIN
  643.  MausForm:= MagicAES.FLATHAND;  SetMouse();
  644. END MouseHand;
  645.  
  646.  
  647. PROCEDURE MouseThincross;
  648. BEGIN
  649.  MausForm:= MagicAES.THINCROSS;  SetMouse();
  650. END MouseThincross;
  651.  
  652.  
  653. PROCEDURE MouseThickcross;
  654. BEGIN
  655.  MausForm:= MagicAES.THICKCROSS;  SetMouse();
  656. END MouseThickcross;
  657.  
  658.  
  659. PROCEDURE MouseOutline;
  660. BEGIN
  661.  MausForm:= MagicAES.OUTLCROSS;  SetMouse();
  662. END MouseOutline;
  663.  
  664.  
  665. PROCEDURE MouseUser;
  666. BEGIN
  667.  MausForm:= MagicAES.USERDEF;  SetMouse();
  668. END MouseUser;
  669.  
  670. PROCEDURE UserMouse (VAR form: MagicTypes.MFORM);
  671. BEGIN
  672.  Usermaus:= ADR(form);
  673. END UserMouse;
  674.  
  675. PROCEDURE SaveMouse ();
  676. BEGIN
  677.   smCount := mouseCount;
  678.   smUser := Usermaus;
  679.   smForm := MausForm;
  680. END SaveMouse;
  681.  
  682. PROCEDURE RestoreMouse();
  683. BEGIN
  684.   Usermaus := smUser;
  685.   MausForm := smForm;
  686.   IF (mouseCount > 0) & (smCount = 0)
  687.   THEN 
  688.     SetMouse();
  689.     ShowMouse (TRUE);
  690.   ELSIF (mouseCount = 0) & (smCount > 0)
  691.   THEN 
  692.     SetMouse();
  693.     HideMouse();
  694.   ELSE
  695.     mouseCount := smCount
  696.   END;
  697. END RestoreMouse;
  698.  
  699. PROCEDURE MouseIsOn () : BOOLEAN;
  700. BEGIN
  701.   RETURN mouseCount = 0;
  702. END MouseIsOn;
  703.  
  704. PROCEDURE HideMouse ();
  705. BEGIN
  706.   IF mouseCount = 0 THEN 
  707.     MagicAES.GrafMouse (MagicAES.MOFF, NIL);
  708.   END;
  709.   INC (mouseCount);
  710. END HideMouse;
  711.  
  712. PROCEDURE ShowMouse (force : BOOLEAN);
  713. BEGIN
  714.   IF (mouseCount > 0) OR force THEN 
  715.     IF mouseCount <= 0 THEN RETURN END;
  716.     DEC (mouseCount);
  717.     IF force THEN mouseCount := 0 END;
  718.     IF mouseCount = 0 THEN MagicAES.GrafMouse (MagicAES.MON, NIL);
  719.     END;
  720.   END;
  721. END ShowMouse;
  722.  
  723. PROCEDURE CursorIsOn (ed : EDITPTR) : BOOLEAN;
  724. BEGIN
  725.   RETURN (ed^.cursor = 0)
  726. END CursorIsOn;
  727.  
  728. VAR inForce : BOOLEAN;
  729.  
  730. PROCEDURE HideCursor (VAR ed : EDITPTR);
  731.   VAR r: Rectangle;
  732. BEGIN
  733.   WITH ed^ DO
  734.     IF isHidden OR inForce THEN RETURN END;
  735.     IF cursor = 0 THEN 
  736.       IF (~readOnly OR multiBlockMark) & (~block OR (block & blockIndent))THEN 
  737.         IF WdwManager.RectList (wdw, 0, r)
  738.         THEN
  739.           REPEAT
  740.             WdwManager.SetClip (cursorHandle, r, TRUE);
  741.             drawCursor (ed, FALSE); 
  742.           UNTIL ~WdwManager.RectList (wdw, 1, r);
  743.         END;
  744.         WdwManager.SetClip (cursorHandle, ed^.editWork, TRUE);
  745.       END;
  746.     END;
  747.     INC (cursor);
  748.   END;
  749. END HideCursor;
  750.  
  751. PROCEDURE ShowCursor (VAR ed : EDITPTR);
  752.   VAR r: Rectangle;
  753. BEGIN
  754.   WITH ed^ DO
  755.     IF isHidden OR inForce THEN RETURN END;
  756.     IF (cursor < 0) THEN HALT END;
  757.     IF cursor > 0 THEN 
  758.       DEC (cursor);
  759.       IF (cursor = 0) & (~readOnly OR multiBlockMark) & (~block OR (block & blockIndent)) THEN 
  760.         IF WdwManager.RectList (wdw, 0, r)
  761.         THEN
  762.           REPEAT
  763.             WdwManager.SetClip (cursorHandle, r, TRUE);
  764.             drawCursor (ed, FALSE); 
  765.           UNTIL ~WdwManager.RectList (wdw, 1, r);
  766.         END;
  767.         WdwManager.SetClip (cursorHandle, ed^.editWork, TRUE);
  768.       END;
  769.     END;
  770.   END;
  771. END ShowCursor;
  772.  
  773. PROCEDURE ForceCursor (VAR ed: EDITPTR);
  774.   VAR xy : ARRAY [0..3] OF INTEGER;
  775.        r : Rectangle;
  776. BEGIN
  777.   WITH ed^ DO
  778.     IF isHidden THEN RETURN END;
  779.     inForce := TRUE;
  780.     cursor := 0;
  781.     getCursorRect (ed, xy);
  782.     WITH r DO x := xy[0]; y := xy[1]; w := xy[2] - xy[0] + 1; h := xy[3] - xy[1] + 1;  END;
  783.     WdwManager.RedrawWdw (wdw, r);
  784.     inForce := FALSE;
  785.     IF (readOnly & ~multiBlockMark) OR (block & ~blockIndent) THEN RETURN END;
  786.     IF WdwManager.RectList (wdw, 0, r)
  787.     THEN
  788.       REPEAT
  789.         WdwManager.SetClip (cursorHandle, r, TRUE);
  790.         drawCursor (ed, FALSE); 
  791.       UNTIL ~WdwManager.RectList (wdw, 1, r);
  792.     END;
  793.     WdwManager.SetClip (cursorHandle, ed^.editWork, TRUE);
  794.   END;
  795. END ForceCursor;
  796.  
  797. BEGIN
  798.   inForce := FALSE;
  799. END EditGlobals.
  800.